#include "func.h"
#include "command.h"

#define BUFFERSIZE 4096
//1、使用TCP协议通信，TCP可靠的，全双工，面向连接，字节流协议
//socket就是一个文件描述符fd来代表，unsigned int 类型
//
//2、TCP传输是一个字节流协议，没有消息边界，
//人为设定一个协议，一个结构体，有确定的大小，
//发送方，接收方遵守这个结构体大小，字节流就有了确定的边界；
//
int main(void) {
    //1、创建套接字socket
    int clientfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(clientfd, -1, "clientfd");

    struct sockaddr_in serveraddr; //存储空间申请在栈上
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8888);//TCP端口号16bit
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //
    //2、向服务器server发起建立连接的请求，connect
    int ret = connect(clientfd, (struct sockaddr* )&serveraddr, sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "connect");
    //printf("sizeof(serveraddr) = %u\n", sizeof(serveraddr));
    printf("connect has complete.\n");

    //3、通信，使用while(1),事件的循环
    char buf[BUFFERSIZE] = {0}; //用户态栈上
    train_t train;  //----定义小火车，用于通信
    //设置邮箱
    fd_set readfds;
    int user_login = 0;  //只用一次，用于用户登录
    while (1) {
        //发送，写,写到内核协议栈，并不是由send发送，
        //send写到内核协议栈，数据的发送操作由内核协议栈完成
        //read默认是一个阻塞式函数
        FD_ZERO(&readfds);
        FD_SET(clientfd, &readfds);
        FD_SET(STDIN_FILENO, &readfds);
        select(clientfd + 1, &readfds, NULL, NULL, NULL);

        memset(buf, 0,  sizeof(buf));

        if (FD_ISSET(STDIN_FILENO, &readfds)) {
            int len = read(STDIN_FILENO, buf, sizeof(buf));
            ERROR_CHECK(len, -1, "read");
            //去掉buf末尾的换行符----重要
            buf[len - 1] = '\0';

            if (user_login < 2) {  //输入用户名和密码时走这个if，user_login为0,1时
                train.length = strlen(buf);
                strncpy(train.buf, buf, train.length);
                //printf("can you see me: %s\n", buf);
                ret = sendn(clientfd, &train, 4 + train.length);  //4,length长度，train.length内容长度
                //printf("send ret = %d\n", ret);
                if (-1 == ret) {
                    puts("sendn failed in client");
                    exit(1);
                }
            }
            else {  //输入完用户名和密码，输入命令走这个else.
                do_command(buf, clientfd);
            }

            //1、对命令做一个解析，是上传，并且文件名正确     
            ////2、若本地不存在这样一个文件，就报一个错误，不执行发送服务器指令
            //若本地存在文件名，发送命令给服务器，执行上传
        }

        //接收，读, 模拟下载文件-----这里还未更改为小火车接收数据！
        memset(buf, 0,  sizeof(buf));
        if (FD_ISSET(clientfd, &readfds)) {
            printf("clientfd is ready.\n");
            ret = recv(clientfd, buf, sizeof(buf), 0);
            //printf("ret = %d\n", ret);
            ERROR_CHECK(ret, -1, "recv in client");
            printf("recv from server:\n%s\n", buf);

            if (!strcmp(buf, ">> please input password:")) {
                user_login++;
            }
            if (!strcmp(buf, ">> login success!\n")) {
                user_login++;
            }
            if (0 == ret) {
                break;
            }
        }
    }

    //1、关闭打开的文件描述符
    close(clientfd);

    return 0;
}
